#!/usr/bin/env python
# -*- mode: python; coding: utf-8; -*-
##--------------------------------------------------------------------------##
##
## Copyright (C) 1998-2003 Markus Oberhumer <markus@oberhumer.com>
## Copyright (C) 2003 Mt. Hood Playing Card Co.
## Copyright (C) 2005-2010 Skomoroh <skomoroh@users.sourceforge.net>
## Copyright (C) 2010-2013 Jeremy Austin-Bardo <tjaustinbardo@gmail.com>
##
## This program is free software: you can redistribute it and/or modify
## it under the terms of the GNU General Public License as published by
## the Free Software Foundation, either version 3 of the License.
##
## This program is distributed in the hope that it will be useful,
## but WITHOUT ANY WARRANTY; without even the implied warranty of
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
## GNU General Public License for more details.
##
## You should have received a copy of the GNU General Public License
## along with this program.  If not, see <http://www.gnu.org/licenses/>.
##
##-- G02 -- S01 ------------------------------------------------------------##
__all__ = []

from .. import autostacks
from .. import comparecards as cmp_cards
from .. import formlib as layout
from .. import helpstrings as hs
from .. import pilelib as stack
from ..gamelib import info as gi, game, state
from ..packlib import info as cs

GT, SL = gi.GT, gi.SL
Wrap = stack.StackWrapper


class SumKing_RowStack(stack.OpenStack):
    """
    Build sum KING. Play top.
    """

    def __init__(self, x, y, game, **cap):
        """
        __init__(x:int, y:int, game:obj[, offset:tup=(0, 3), *capability*])
          -> None

        :param integer x: left x-coordinate.
        :param integer y: top y-coordinate.
        :param object game: current Game.
        :param integer suit: pile's suit and base_suit
        :keyword tuple offset: offset from left and offset from top

        seealso::
          Module pysollib.stackcaps with details of *capability* keywords.
        """
        cap.setdefault('offset', (0, 3))
        super(SumKing_RowStack, self).__init__(x, y, game, **cap)

    def _sequence(self, cards):
        """
        _sequence(cards:seq) -> bool

        Checks sequence rank sum is 15. and cards < TEN.

        :param sequence cards: cards from sending pile
        :return: pile accepts cards?
        :rtype: boolean
        """
        return cmp_cards.sumOf(cards, cs.KING)

    def cardsBuild(self, from_stack, cards):
        """
        cardsBuild(from_stack:obj, cards:seq) -> bool

        Cards build according parent cardsBuild(), and whether play cards
        and top card _sequence().

        :param object from_stack: sending pile
        :param sequence cards: cards from sending pile
        :return: pile accepts cards?
        :rtype: boolean
        """
        if not super(SumKing_RowStack, self).cardsBuild(from_stack,
                                                             cards):
            return False
        return self._sequence(self.cards[-1:] + cards)

    @property
    def _helpString(self):
        """
        _helpString -> str

        :return: helpful string about pile for its canvas label.
        :rtype:  base_string
        """
        return hs.PAIR_SUM_KING


class EiffelTower(game.Game):
    """
    Clear cards from _talon_ and _waste_ within 1 turn.

    _row_
      Pile 20 in pyramid 6 high. Init deal 1 card. Build sum 13. Play top.

    _talon_
      Pile 1 W. Deal _waste_ 1 card.

    _waste_
      Pile 1 E of _talon_. Init deal 1 card. Build none. Play top.

    note::
      ⟪autoflip⟫, ⟪autoplay⟫, ⟪quickplay⟫ disabled.
    ------
    :cvar Stack _talon_: stack.WasteTalon
    :cvar Stack _waste_: stack.WasteStack
    :cvar Stack _row_: SumKing_RowStack
    :cvar Hint _hint_: hint.DefaultHint
    """
    __info__ = dict(id=16, name='Eiffel Tower', game_type=(GT.PAIRING |
                    GT.ATARI), decks=2, skill_level=SL.MOSTLY_LUCK,
                    version='1.11')
    __author__ = 'Markus Oberhumer'
    __version__ = 7.70

    _talon_ = stack.WasteTalon
    _waste_ = stack.WasteStack
    _row_ = SumKing_RowStack

    def _create_game(self, **kw):
        """
        Create game format.

        Overide pile placements based on current group attributes alone.

        .. \_create_game() -> Layout
        """
        l, s = layout.Layout(self), self.s
        self.table_size = (l.XM + 17 * l.HXS, l.YM + 6 * l.YS,)
        for y, row, dx in zip(l.col_iter(l.YM, 7), range(1, 6) + [5],
                              range(5, 0, -1) + [1]):
            for x in l.row_iter(l.XM + dx * l.HXS, row):
                s['rows'].append(self._row_(x, y, game=self, offset=(0, 3)))
        x, y = self.width - l.XS, self.height / 2
        s['talon'] = self._talon_(x, y, game=self)
        l.set_ncards_text(s['talon'], 's')
        x -= l.XS
        s['wastes'] = [self._waste_(x, y, game=self)]
        l.set_ncards_text(s['wastes'][-1], 's')
        l.defaultStackGroups()
        return l

    def _start(self, *kws):
        """
        Deal initial cards for new game.
          - s[rows]: 1 ea.

        .. \_start([]) -> None
        """
        self.s['talon'].dealRow()

    @property
    def is_complete(self):
        return all([not self.s['talon'].cards, not self.s['wastes'][-1].cards])

    def _autopiles(self, event=None):
        """
        Return piles for auto or quick move.

        Overide to disable autoflip, autodrop and quickplay.

        .. \_autopiles(self, event=None) -> seq(seq(Pile ...), seq(Pile ...),
             seq(Pile ...))
        """
        return autostacks.none()


class StrictEiffelTower(EiffelTower):
    """
    Clear cards from _talon_ and _waste_ within 1 turn.

    _row_
      Pile 20 in pyramid 6 high. Init deal 1 card. Build sum 13. Play top.

    _talon_
      Pile 1 W. Deal _waste_ 1 card.

    _waste_
      Pile 1 E of _talon_. Init deal 1 card. Build none. Play top. Max 2 card.

    note::
      ⟪autoflip⟫, ⟪autoplay⟫, ⟪quickplay⟫ disabled.
    ------
    :cvar Stack _talon_: stack.WasteTalon
    :cvar Stack _waste_: stack.WasteStack (max_cards=2)
    :cvar Stack _row_: SumKing_RowStack
    :cvar Hint _hint_: hint.DefaultHint
    """
    __info__ = dict(id=801, name='Strict Eiffel Tower',
                    game_type=(GT.PAIRING | GT.HIDDEN), decks=2,
                    skill_level=SL.MOSTLY_LUCK, version='0.70up')
    __author__ = 'Skomoroh'
    __version__ = 7.70

    _waste_ = Wrap(stack.WasteStack, max_cards=2)


PROVIDES = [EiffelTower, StrictEiffelTower]